home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / mig / dist / routine.h < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-28  |  18.3 KB  |  472 lines

  1. /* 
  2.  * Mach Operating System
  3.  * Copyright (c) 1991,1990 Carnegie Mellon University
  4.  * All Rights Reserved.
  5.  * 
  6.  * Permission to use, copy, modify and distribute this software and its
  7.  * documentation is hereby granted, provided that both the copyright
  8.  * notice and this permission notice appear in all copies of the
  9.  * software, derivative works or modified versions, and any portions
  10.  * thereof, and that both notices appear in supporting documentation.
  11.  * 
  12.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14.  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15.  * 
  16.  * Carnegie Mellon requests users of this software to return to
  17.  * 
  18.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  19.  *  School of Computer Science
  20.  *  Carnegie Mellon University
  21.  *  Pittsburgh PA 15213-3890
  22.  * 
  23.  * any improvements or extensions that they make and grant Carnegie Mellon
  24.  * the rights to redistribute these changes.
  25.  */
  26. /*
  27.  * HISTORY
  28.  * $Log:    routine.h,v $
  29.  * Revision 2.7  92/01/14  16:46:34  rpd
  30.  *     Removed akbWasInOut.  Added akeCountInOut, argCInOut.
  31.  *     [92/01/08            rpd]
  32.  * 
  33.  * Revision 2.6  92/01/03  20:29:52  dbg
  34.  *     Add byReferenceUser and byReferenceServer to each argument, so
  35.  *     they can be individually set.  Add akbPointer.
  36.  *     [91/09/04            dbg]
  37.  * 
  38.  * Revision 2.5  91/08/28  11:17:17  jsb
  39.  *     Removed Camelot and TrapRoutine support.
  40.  *     Changed MsgKind to MsgSeqno.
  41.  *     [91/08/12            rpd]
  42.  * 
  43.  * Revision 2.4  91/07/31  18:10:37  dbg
  44.  *     Add akbIndefinite, argServerCopy.
  45.  *     [91/04/10            dbg]
  46.  * 
  47.  *     Change argDeallocate to an enumerated type, to allow for
  48.  *     user-specified deallocate flag.
  49.  * 
  50.  *     Add rtCheckMaskFunction.  Add rtNoReplyArgs to routine
  51.  *     structure.
  52.  *     [91/04/03            dbg]
  53.  * 
  54.  * Revision 2.3  91/02/05  17:55:28  mrt
  55.  *     Changed to new Mach copyright
  56.  *     [91/02/01  17:55:21  mrt]
  57.  * 
  58.  * Revision 2.2  90/06/02  15:05:23  rpd
  59.  *     Created for new IPC.
  60.  *     [90/03/26  21:12:57  rpd]
  61.  * 
  62.  * 07-Apr-89  Richard Draves (rpd) at Carnegie-Mellon University
  63.  *    Extensive revamping.  Added polymorphic arguments.
  64.  *    Allow multiple variable-sized inline arguments in messages.
  65.  *
  66.  * 20-Dec-87  David Golub (dbg) at Carnegie-Mellon University
  67.  *    Added pointers to last Request and Reply arguments.
  68.  *    Added flag to show that (only) last argument is variable-sized.
  69.  *    Added argMultiplier field for count arguments, where parent
  70.  *    argument is itself a multiple of an IPC type.
  71.  *
  72.  * 16-Nov-87  David Golub (dbg) at Carnegie-Mellon University
  73.  *    Don't add akbVarNeeded attribute here - server.c can
  74.  *    better determine whether it is needed.
  75.  *
  76.  * 21-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
  77.  *    Added argFlag field to argument_t
  78.  *
  79.  * 18-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
  80.  *    Changed akTid to omit akServerArg
  81.  *    Changed arg_kind_t to u_int to make code more obvious and
  82.  *    to get rid of compiler warnings and to give hc a chance.
  83.  *    Changed flags on akTid, akDummy.
  84.  *
  85.  * 10-Aug-87  Mary Thompson (mrt) at Carnegie-Mellon University
  86.  *    Added defines need to make MsgType a legitimate argument type
  87.  *
  88.  * 28-May-87  Richard Draves (rpd) at Carnegie-Mellon University
  89.  *    Created.
  90.  */
  91.  
  92. #ifndef    _ROUTINE_H
  93. #define    _ROUTINE_H
  94.  
  95. #define    EXPORT_BOOLEAN
  96. #include <mach/boolean.h>
  97. #include <sys/types.h>
  98. #include "type.h"
  99.  
  100. /* base kind arg */
  101. #define akeNone        (0)
  102. #define akeNormal    (1)    /* a normal, user-defined argument */
  103. #define akeRequestPort    (2)    /* pointed at by rtRequestPort */
  104. #define akeWaitTime    (3)    /* pointed at by rtWaitTime */
  105. #define akeReplyPort    (4)    /* pointed at by rtReplyPort */
  106. #define akeMsgOption    (5)    /* pointed at by rtMsgOption */
  107. #define akeMsgSeqno    (6)    /* pointed at by rtMsgSeqno */
  108. #define akeRetCode    (7)    /* pointed at by rtRetCode/rtReturn */
  109. #define akeReturn    (8)    /* pointed at by rtReturn */
  110. #define akeCount    (9)    /* a count arg for argParent */
  111. #define akePoly        (10)    /* a poly arg for argParent */
  112. #define    akeDealloc    (11)    /* a deallocate arg for argParent */
  113. #define    akeServerCopy    (12)    /* a server-copy arg for argParent */
  114. #define akeCountInOut    (13)    /* a count-in-out arg */
  115.  
  116. #define    akeBITS        (0x0000003f)
  117. #define    akbRequest    (0x00000040)    /* has a msg_type in request */
  118. #define    akbReply    (0x00000080)    /* has a msg_type in reply */
  119. #define    akbUserArg    (0x00000100)    /* an arg on user-side */
  120. #define    akbServerArg    (0x00000200)    /* an arg on server-side  */
  121. #define akbSend        (0x00000400)    /* value carried in request */
  122. #define akbSendBody    (0x00000800)    /* value carried in request body */
  123. #define akbSendSnd    (0x00001000)    /* value stuffed into request */
  124. #define akbSendRcv    (0x00002000)    /* value grabbed from request */
  125. #define akbReturn    (0x00004000)    /* value carried in reply */
  126. #define akbReturnBody    (0x00008000)    /* value carried in reply body */
  127. #define akbReturnSnd    (0x00010000)    /* value stuffed into reply */
  128. #define akbReturnRcv    (0x00020000)    /* value grabbed from reply */
  129. #define akbReplyInit    (0x00040000)    /* reply msg-type must be init'ed */
  130. #define akbRequestQC    (0x00080000)    /* msg_type can be checked quickly */
  131. #define akbReplyQC    (0x00100000)    /* msg_type can be checked quickly */
  132. #define akbReplyCopy    (0x00200000)    /* copy reply value from request */
  133. #define akbVarNeeded    (0x00400000)    /* may need local var in server */
  134. #define akbDestroy    (0x00800000)    /* call destructor function */
  135. #define akbVariable    (0x01000000)    /* variable size inline data */
  136. #define    akbIndefinite    (0x02000000)    /* variable size, inline or out */
  137. #define    akbPointer    (0x04000000)    /* server gets a pointer to the
  138.                        real buffer */
  139. /* be careful, there aren't many bits left */
  140.  
  141. typedef u_int  arg_kind_t;
  142.  
  143. /*
  144.  * akbRequest means msg_type/data fields are allocated in the request
  145.  * msg.  akbReply means msg_type/data fields are allocated in the
  146.  * reply msg.  These bits (with akbReplyInit, akbRequestQC, akbReplyQC)
  147.  * control msg structure declarations packing, and checking of
  148.  * mach_msg_type_t fields.
  149.  *
  150.  * akbUserArg means this argument is an argument to the user-side stub.
  151.  * akbServerArg means this argument is an argument to
  152.  * the server procedure called by the server-side stub.
  153.  *
  154.  * The akbSend* and akbReturn* bits control packing/extracting values
  155.  * in the request and reply messages.
  156.  *
  157.  * akbSend means the argument's value is carried in the request msg.
  158.  * akbSendBody implies akbSend; the value is carried in the msg body.
  159.  * akbSendSnd implies akbSend; the value is stuffed into the request.
  160.  * akbSendRcv implies akbSend; the value is pulled out of the request.
  161.  *
  162.  * akbReturn, akbReturnBody, akbReturnSnd, akbReturnRcv are defined
  163.  * similarly but apply to the reply message.
  164.  *
  165.  * User-side code generation (header.c, user.c) and associated code
  166.  * should use akbSendSnd and akbReturnRcv, but not akbSendRcv and
  167.  * akbReturnSnd.  Server-side code generation (server.c) is reversed.
  168.  * Code generation should use the more specific akb{Send,Return}{Snd,Rcv}
  169.  * bits when possible, instead of akb{Send,Return}.
  170.  *
  171.  * Note that akRetCode and akReturn lack any Return bits, although
  172.  * there is a value in the msg.  These guys are packed/unpacked
  173.  * with special code, unlike other arguments.
  174.  *
  175.  * akbReplyInit implies akbReply.  It means the server-side stub
  176.  * should initialize the argument's msg_type field in the reply msg.
  177.  * Some special arguments (RetCode, Dummy, Tid) have their msg_type
  178.  * fields in the reply message initialized by the server demux
  179.  * function; these arguments have akbReply but not akbReplyInit.
  180.  *
  181.  * akbRequestQC implies akbRequest.  If it's on, then the
  182.  * mach_msg_type_t value in the request message can be checked quickly
  183.  * (by casting to an int and checking with a single comparison).
  184.  * akbReplyQC has the analogous meaning with respect to akbReply.
  185.  *
  186.  * akbVariable means the argument has variable-sized inline data.
  187.  * It isn't currently used for code generation, but routine.c
  188.  * does use it internally.  It is added in rtAugmentArgKind.
  189.  *
  190.  * akbReplyCopy and akbVarNeeded help control code generation in the
  191.  * server-side stub.  The preferred method of handling data in the
  192.  * server-side stub avoids copying into/out-of local variables.  In
  193.  * arguments get passed directly to the server proc from the request msg.
  194.  * Out arguments get stuffed directly into the reply msg by the server proc.
  195.  * For InOut arguments, the server proc gets the address of the data in
  196.  * the request msg, and the resulting data gets copied to the reply msg.
  197.  * Some arguments need a local variable in the server-side stub.  The
  198.  * code extracts the data from the request msg into the variable, and
  199.  * stuff the reply msg from the variable.
  200.  *
  201.  * akbReplyCopy implies akbReply.  It means the data should get copied
  202.  * from the request msg to the reply msg after the server proc is called.
  203.  * It is only used by akInOut.  akTid doesn't need it because the tid
  204.  * data in the reply msg is initialized in the server demux function.
  205.  *
  206.  * akbVarNeeded means the argument needs a local variable in the
  207.  * server-side stub.  It is added in rtAugmentArgKind and
  208.  * rtCheckVariable.  An argument shouldn't have all three of
  209.  * akbReturnSnd, akbVarNeeded and akbReplyCopy, because this indicates
  210.  * the reply msg should be stuffed both ways.
  211.  *
  212.  * akbDestroy helps control code generation in the server-side stub.
  213.  * It means this argument has a destructor function which should be called.
  214.  *
  215.  * Header file generation (header.c) uses:
  216.  *    akbUserArg
  217.  *
  218.  * User stub generation (user.c) uses:
  219.  *    akbUserArg, akbRequest, akbReply, akbSendSnd,
  220.  *    akbSendBody, akbReturnRcv, akbReplyQC
  221.  *
  222.  * Server stub generation (server.c) uses:
  223.  *    akbServerArg, akbRequest, akbReply, akbSendRcv, akbReturnSnd,
  224.  *    akbReplyInit, akbReplyCopy, akbVarNeeded, akbSendBody, akbRequestQC
  225.  *
  226.  *
  227.  * During code generation, the routine, argument, and type data structures
  228.  * are read-only.  The code generation functions' output is their only
  229.  * side-effect.
  230.  *
  231.  *
  232.  * Style note:
  233.  * Code can use logical operators (|, &, ~) on akb values.
  234.  * ak values should be manipulated with the ak functions.
  235.  */
  236.  
  237. /* various useful combinations */
  238.  
  239. #define akbNone        (0)
  240. #define akbAll        (~akbNone)
  241. #define akbAllBits    (~akeBITS)
  242.  
  243. #define akbSendBits    (akbSend|akbSendBody|akbSendSnd|akbSendRcv)
  244. #define akbReturnBits    (akbReturn|akbReturnBody|akbReturnSnd|akbReturnRcv)
  245. #define akbSendReturnBits    (akbSendBits|akbReturnBits)
  246.  
  247. #define akNone        akeNone
  248.  
  249. #define akIn        akAddFeature(akeNormal,                \
  250.     akbUserArg|akbServerArg|akbRequest|akbSendBits)
  251.  
  252. #define akOut        akAddFeature(akeNormal,                \
  253.     akbUserArg|akbServerArg|akbReply|akbReturnBits|akbReplyInit)
  254.  
  255. #define akInOut        akAddFeature(akeNormal,                \
  256.     akbUserArg|akbServerArg|akbRequest|akbReply|            \
  257.     akbSendBits|akbReturnBits|akbReplyInit|akbReplyCopy)
  258.  
  259. #define akRequestPort    akAddFeature(akeRequestPort,            \
  260.     akbUserArg|akbServerArg|akbSend|akbSendSnd|akbSendRcv)
  261.  
  262. #define akWaitTime    akAddFeature(akeWaitTime, akbUserArg)
  263.  
  264. #define akMsgOption    akAddFeature(akeMsgOption, akbUserArg)
  265.  
  266. #define akMsgSeqno    akAddFeature(akeMsgSeqno,            \
  267.     akbServerArg|akbSend|akbSendRcv)
  268.  
  269. #define akReplyPort    akAddFeature(akeReplyPort,            \
  270.     akbUserArg|akbServerArg|akbSend|akbSendSnd|akbSendRcv)
  271.  
  272. #define akUReplyPort    akAddFeature(akeReplyPort,            \
  273.     akbUserArg|akbSend|akbSendSnd|akbSendRcv)
  274.  
  275. #define akSReplyPort    akAddFeature(akeReplyPort,            \
  276.     akbServerArg|akbSend|akbSendSnd|akbSendRcv)
  277.  
  278. #define akRetCode    akAddFeature(akeRetCode, akbReply)
  279.  
  280. #define akReturn    akAddFeature(akeReturn,                \
  281.     akbReply|akbReplyInit)
  282.  
  283. #define akCount        akAddFeature(akeCount,                \
  284.     akbUserArg|akbServerArg)
  285.  
  286. #define akPoly        akePoly
  287.  
  288. #define    akDealloc    akAddFeature(akeDealloc, akbUserArg)
  289.  
  290. #define    akServerCopy    akAddFeature(akeServerCopy, akbServerArg|akbSendRcv)
  291.  
  292. #define akCountInOut    akAddFeature(akeCountInOut, akbRequest|akbSendBits)
  293.  
  294. #define    akCheck(ak, bits)    ((ak) & (bits))
  295. #define akCheckAll(ak, bits)    (akCheck(ak, bits) == (bits))
  296. #define akAddFeature(ak, bits)    ((ak)|(bits))
  297. #define akRemFeature(ak, bits)    ((ak)&~(bits))
  298. #define akIdent(ak)        ((ak) & akeBITS)
  299.  
  300. /*
  301.  * The arguments to a routine/function are linked in left-to-right order.
  302.  * argName is used for error messages and pretty-printing,
  303.  * not code generation.  Code generation shouldn't make any assumptions
  304.  * about the order of arguments, esp. count and poly arguments.
  305.  * (Unfortunately, code generation for inline variable-sized arguments
  306.  * does make such assumptions.)
  307.  *
  308.  * argVarName is the name used in generated code for function arguments
  309.  * and local variable names.  argMsgField is the name used in generated
  310.  * code for the field in msgs where the argument's value lives.
  311.  * argTTName is the name used in generated code for msg-type fields and
  312.  * static variables used to initialize those fields.  argPadName is the
  313.  * name used in generated code for a padding field in msgs.
  314.  *
  315.  * argFlags can be used to override the deallocate and longform bits
  316.  * in the argument's type.  rtProcessArgFlags sets argDeallocate and
  317.  * argLongForm from it and the type.  Code generation shouldn't use
  318.  * argFlags.
  319.  *
  320.  * argCount, argPoly, and argDealloc get to the implicit count, poly,
  321.  * and dealloc arguments associated with the argument; they should be
  322.  * used instead of argNext.  In these implicit arguments, argParent is
  323.  * a pointer to the "real" arg.
  324.  *
  325.  * In count arguments, argMultiplier is a scaling factor applied to
  326.  * the count arg's value to get msg-type-number.  It is equal to
  327.  *    argParent->argType->itElement->itNumber
  328.  */
  329.  
  330. typedef struct argument
  331. {
  332.     /* if argKind == akReturn, then argName is name of the function */
  333.     identifier_t argName;
  334.     struct argument *argNext;
  335.  
  336.     arg_kind_t argKind;
  337.     ipc_type_t *argType;
  338.  
  339.     string_t argVarName;    /* local variable and argument names */
  340.     string_t argMsgField;    /* message field's name */
  341.     string_t argTTName;        /* name for msg_type fields, static vars */
  342.     string_t argPadName;    /* name for pad field in msg */
  343.  
  344.     ipc_flags_t argFlags;
  345.     dealloc_t argDeallocate;    /* overrides argType->itDeallocate */
  346.     boolean_t argLongForm;    /* overrides argType->itLongForm */
  347.     boolean_t argServerCopy;
  348.     boolean_t argCountInOut;
  349.  
  350.     struct routine *argRoutine;    /* routine we are part of */
  351.  
  352.     struct argument *argCount;    /* our count arg, if present */
  353.     struct argument *argCInOut;    /* our CountInOut arg, if present */
  354.     struct argument *argPoly;    /* our poly arg, if present */
  355.     struct argument *argDealloc;/* our dealloc arg, if present */
  356.     struct argument *argSCopy;    /* our serverCopy arg, if present */
  357.     struct argument *argParent;    /* in a count or poly arg, the base arg */
  358.     int argMultiplier;        /* for Count argument: parent is a multiple
  359.                    of a basic IPC type.  Argument must be
  360.                    multiplied by Multiplier to get IPC
  361.                    number-of-elements. */
  362.  
  363.     /* how variable/inline args precede this one, in request and reply */
  364.     int argRequestPos;
  365.     int argReplyPos;
  366.     /* whether argument is by reference, on user and server side */
  367.     boolean_t    argByReferenceUser;
  368.     boolean_t    argByReferenceServer;
  369. } argument_t;
  370.  
  371. /*
  372.  * The various routine kinds' peculiarities are abstracted by rtCheckRoutine
  373.  * into attributes like rtOneWay, rtProcedure, etc.  These are what
  374.  * code generation should use.  It is Bad Form for code generation to
  375.  * test rtKind.
  376.  */
  377.  
  378. typedef enum
  379. {
  380.     rkRoutine,
  381.     rkSimpleRoutine,
  382.     rkSimpleProcedure,
  383.     rkProcedure,
  384.     rkFunction,
  385. } routine_kind_t;
  386.  
  387. typedef struct routine
  388. {
  389.     identifier_t rtName;
  390.     routine_kind_t rtKind;
  391.     argument_t *rtArgs;
  392.     u_int rtNumber;        /* used for making msg ids */
  393.  
  394.     identifier_t rtUserName;    /* user-visible name (UserPrefix + Name) */
  395.     identifier_t rtServerName;    /* server-side name (ServerPrefix + Name) */
  396.  
  397.     /* rtErrorName is only used for Procs, SimpleProcs, & Functions */
  398.     identifier_t rtErrorName;    /* error-handler name */
  399.  
  400.     boolean_t rtOneWay;        /* SimpleProcedure or SimpleRoutine */
  401.     boolean_t rtProcedure;    /* Procedure or SimpleProcedure */
  402.     boolean_t rtUseError;    /* Procedure or Function */
  403.  
  404.     boolean_t rtSimpleFixedRequest;    /* fixed msg-simple value in request */
  405.     boolean_t rtSimpleSendRequest;    /* in any case, initial value */
  406.     boolean_t rtSimpleCheckRequest;    /* check msg-simple in request */
  407.     boolean_t rtSimpleReceiveRequest;    /* if so, the expected value */
  408.  
  409.     boolean_t rtSimpleFixedReply;    /* fixed msg-simple value in reply */
  410.     boolean_t rtSimpleSendReply;    /* in any case, initial value */
  411.     boolean_t rtSimpleCheckReply;    /* check msg-simple in reply */
  412.     boolean_t rtSimpleReceiveReply;    /* if so, the expected value */
  413.  
  414.     u_int rtRequestSize;    /* minimal size of a legal request msg */
  415.     u_int rtReplySize;        /* minimal size of a legal reply msg */
  416.  
  417.     int rtNumRequestVar;    /* number of variable/inline args in request */
  418.     int rtNumReplyVar;        /* number of variable/inline args in reply */
  419.  
  420.     int rtMaxRequestPos;    /* maximum of argRequestPos */
  421.     int rtMaxReplyPos;        /* maximum of argReplyPos */
  422.  
  423.     boolean_t rtNoReplyArgs;    /* if so, no reply message arguments beyond
  424.                    what the server dispatch routine inserts */
  425.  
  426.     /* distinguished arguments */
  427.     argument_t *rtRequestPort;    /* always non-NULL, defaults to first arg */
  428.     argument_t *rtReplyPort;    /* always non-NULL, defaults to Mig-supplied */
  429.     argument_t *rtReturn;    /* non-NULL unless rtProcedure */
  430.     argument_t *rtServerReturn;    /* NULL or rtReturn  */
  431.     argument_t *rtRetCode;    /* always non-NULL */
  432.     argument_t *rtWaitTime;    /* if non-NULL, will use MACH_RCV_TIMEOUT */
  433.     argument_t *rtMsgOption;    /* always non-NULL, defaults to NONE */
  434.     argument_t *rtMsgSeqno;    /* if non-NULL, server gets passed seqno */
  435. } routine_t;
  436.  
  437. #define rtNULL        ((routine_t *) 0)
  438. #define argNULL        ((argument_t *) 0)
  439.  
  440. extern u_int rtNumber;
  441. /* rt->rtNumber will be initialized */
  442. extern routine_t *rtAlloc();
  443. /* skip a number */
  444. extern void rtSkip();
  445.  
  446. extern argument_t *argAlloc();
  447.  
  448. extern boolean_t
  449. rtCheckMask(/* argument_t *args, u_int mask */);
  450.  
  451. extern boolean_t
  452. rtCheckMaskFunction(/* argument_t *args, u_int mask,
  453.         boolean_t (*func)(argument_t *arg) */);
  454.  
  455. extern routine_t *
  456. rtMakeRoutine(/* identifier_t name, argument_t *args */);
  457. extern routine_t *
  458. rtMakeSimpleRoutine(/* identifier_t name, argument_t *args */);
  459. extern routine_t *
  460. rtMakeProcedure(/* identifier_t name, argument_t *args */);
  461. extern routine_t *
  462. rtMakeSimpleProcedure(/* identifier_t name, argument_t *args */);
  463. extern routine_t *
  464. rtMakeFunction(/* identifier_t name, argument_t *args, ipc_type_t *type */);
  465.  
  466. extern void rtPrintRoutine(/* routine_t *rt */);
  467. extern void rtCheckRoutine(/* routine_t *rt */);
  468.  
  469. extern char *rtRoutineKindToStr(/* routine_kind_t rk */);
  470.  
  471. #endif    _ROUTINE_H
  472.